package com.xunqi.ad.service.impl;

import com.xunqi.ad.entity.AdPlan;
import com.xunqi.ad.entity.AdUnit;
import com.xunqi.ad.entity.unit_condition.AdUnitDistrict;
import com.xunqi.ad.entity.unit_condition.AdUnitIt;
import com.xunqi.ad.entity.unit_condition.AdUnitKeyword;
import com.xunqi.ad.entity.unit_condition.CreativeUnit;
import com.xunqi.ad.enums.ResponseEnum;
import com.xunqi.ad.exception.AdException;
import com.xunqi.ad.form.*;
import com.xunqi.ad.repository.AdPlanRepository;
import com.xunqi.ad.repository.AdUnitRepository;
import com.xunqi.ad.repository.CreativeRepository;
import com.xunqi.ad.repository.unit_condition.AdUnitDistrictRepository;
import com.xunqi.ad.repository.unit_condition.AdUnitItRepository;
import com.xunqi.ad.repository.unit_condition.AdUnitKeyWordRepository;
import com.xunqi.ad.repository.unit_condition.CreativeUnitRepository;
import com.xunqi.ad.service.IAdUnitService;
import com.xunqi.ad.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Created with IntelliJ IDEA.
 * @author: 夏沫止水
 * @createTime: 2020-04-30 15:21
 **/
@Service("adUnitService")
public class AdUnitServiceImpl implements IAdUnitService {

    @Resource
    private AdPlanRepository adPlanRepository;

    @Resource
    private AdUnitRepository adUnitRepository;

    @Resource
    private AdUnitKeyWordRepository adUnitKeyWordRepository;

    @Resource
    private AdUnitItRepository adUnitItRepository;

    @Resource
    private AdUnitDistrictRepository adUnitDistrictRepository;

    @Resource
    private CreativeRepository creativeRepository;

    @Resource
    private CreativeUnitRepository creativeUnitRepository;

    /**
     * 创建推广单元
     * @param form
     * @return
     * @throws AdException
     */
    @Override
    public ResponseVo<AdUnitResponseVo> createUnit(AdUnitForm form) throws AdException {

        //查询推广计划信息
        Optional<AdPlan> adPlan = adPlanRepository.findById(form.getPlanId());

        if (!adPlan.isPresent()) {
            return ResponseVo.error(ResponseEnum.CAN_NOT_FIND_RECORD);
        }

        //查询数据库是否有存在相同的推广单元信息
        AdUnit oldAdUnit = adUnitRepository.findByPlanIdAndUnitName(form.getPlanId(),
                form.getUnitName());
        if (oldAdUnit != null) {
            return ResponseVo.error(ResponseEnum.SAME_NAME_UNIT_ERROR);
        }

        //数据的赋值，对数据进行保存
        AdUnit adUnit = new AdUnit(form.getPlanId(),form.getUnitName(),form.getPositionType(),form.getBudget());
        AdUnit unitSave = adUnitRepository.save(adUnit);

        AdUnitResponseVo adUnitResponseVo = new AdUnitResponseVo();
        BeanUtils.copyProperties(unitSave,adUnitResponseVo);

        return ResponseVo.success(adUnitResponseVo);
    }


    /**
     * 创建关联关键词限制信息
     * @param form
     * @return
     * @throws AdException
     */
    @Override
    public ResponseVo<AdUnitKeywordResponseVo> createUnitKeyword(AdUnitKeywordForm form) throws AdException {

        List<Long> unitIds = form.getUnitKeywords().stream()
                .map(AdUnitKeywordForm.UnitKeyword::getUnitId)
                .collect(Collectors.toList());

        if (!isRelatedUnitExist(unitIds)) {
            return ResponseVo.error(ResponseEnum.PARAM_ERROR);
        }

        List<Long> ids = Collections.emptyList();

        List<AdUnitKeyword> unitKeywords = new ArrayList<>();
        if (!CollectionUtils.isEmpty(form.getUnitKeywords())) {

            form.getUnitKeywords().forEach(e -> unitKeywords.add(
                    new AdUnitKeyword(e.getUnitId(),e.getKeyword())
            ));


            ids = adUnitKeyWordRepository.saveAll(unitKeywords).stream()
                    .map(e -> e.getId())
                    .collect(Collectors.toList());
        }

        AdUnitKeywordResponseVo responseVo = new AdUnitKeywordResponseVo(ids);

        return ResponseVo.success(responseVo);
    }


    /**
     * 创建关联兴趣限制信息
     * @param form
     * @return
     * @throws AdException
     */
    @Override
    public ResponseVo<AdUnitItResponseVo> createUnitIt(AdUnitItForm form) throws AdException {

        List<Long> unitIds = form.getUnitIts().stream()
                .map(AdUnitItForm.UnitIt::getUnitId)
                .collect(Collectors.toList());

        if (!isRelatedUnitExist(unitIds)) {
            return ResponseVo.error(ResponseEnum.PARAM_ERROR);
        }

        List<AdUnitIt> unitIts = new ArrayList<>();
        form.getUnitIts().forEach(e -> unitIts.add(
                new AdUnitIt(e.getUnitId(),e.getItTag())
        ));

        List<Long> ids = adUnitItRepository.saveAll(unitIts).stream()
                .map(AdUnitIt::getId)
                .collect(Collectors.toList());

        AdUnitItResponseVo responseVo = new AdUnitItResponseVo(ids);

        return ResponseVo.success(responseVo);
    }


    /**
     * 创建关联推广单元地域限制信息
     * @param form
     * @return
     * @throws AdException
     */
    @Override
    public ResponseVo<AdUnitDistrictResponseVo> createUnitDistrict(AdUnitDistrictForm form) throws AdException {

        List<Long> unitIds = form.getUnitDistricts().stream()
                .map(AdUnitDistrictForm.UnitDistrict::getUnitId)
                .collect(Collectors.toList());

        if (!isRelatedUnitExist(unitIds)) {
            return ResponseVo.error(ResponseEnum.PARAM_ERROR);
        }

        List<AdUnitDistrict> unitDistricts = new ArrayList<>();
        form.getUnitDistricts().forEach(e -> unitDistricts.add(
                new AdUnitDistrict(e.getUnitId(),e.getProvince(),e.getCity())
        ));

        List<Long> ids = adUnitDistrictRepository.saveAll(unitDistricts).stream()
                .map(e -> e.getId()).collect(Collectors.toList());

        AdUnitDistrictResponseVo responseVo = new AdUnitDistrictResponseVo();

        return ResponseVo.success(responseVo);
    }

    /**
     * 创建创意表与推广单元管理的信息
     * @param form
     * @return
     * @throws AdException
     */
    @Override
    public ResponseVo<CreativeUnitResponseVo> createCreativeUnit(CreativeUnitForm form) throws AdException {

        List<Long> unitIds = form.getUnitItems().stream()
                .map(CreativeUnitForm.CreativeUnitItem::getUnitId)
                .collect(Collectors.toList());

        List<Long> creativeIds = form.getUnitItems().stream()
                .map(CreativeUnitForm.CreativeUnitItem::getCreativeId)
                .collect(Collectors.toList());

        if (!(isRelatedUnitExist(unitIds) && isRelatedCreativeExist(creativeIds))) {
            return ResponseVo.error(ResponseEnum.PARAM_ERROR);
        }

        List<CreativeUnit> creativeUnits = new ArrayList<>();
        form.getUnitItems().forEach(e -> creativeUnits.add(
                new CreativeUnit(e.getCreativeId(),e.getUnitId())
        ));

        //批量新增
        List<Long> ids = creativeUnitRepository.saveAll(creativeUnits).stream()
                .map(CreativeUnit::getId)
                .collect(Collectors.toList());

        CreativeUnitResponseVo creativeUnitResponseVo = new CreativeUnitResponseVo(ids);

        return ResponseVo.success(creativeUnitResponseVo);
    }

    /**
     * 效验参数
     * @return
     */
    private boolean isRelatedUnitExist(List<Long> unitIds) {

        if (CollectionUtils.isEmpty(unitIds)) {
            return false;
        }

        int unitIdSize = adUnitRepository.findAllById(unitIds).size();
        int size = new HashSet<>(unitIds).size();
        return unitIdSize == size;
    }

    private boolean isRelatedCreativeExist(List<Long> creativeIds) {

        if (CollectionUtils.isEmpty(creativeIds)) {
            return false;
        }

        HashSet<Long> idSet = new HashSet<>(creativeIds);
        int size = creativeRepository.findAllById(creativeIds).size();

        return size == idSet.size();
    }

}
